package com.zbkj.crmeb.store.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.CommonPage;
import com.common.PageParamRequest;
import com.constants.Constants;
import com.crmeb.core.config.MybatisPlusConfig;
import com.crmeb.core.exception.CrmebException;
import com.crmeb.core.utils.TableNameUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.crmeb.chant.model.ChannelMerchant;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.zbkj.crmeb.store.dao.StoreProductDistributeDao;
import com.zbkj.crmeb.store.model.*;
import com.zbkj.crmeb.store.request.StoreProductDistributeRequest;
import com.zbkj.crmeb.store.response.StoreProductDistributeResponse;
import com.zbkj.crmeb.store.service.*;
import com.zbkj.crmeb.system.service.SystemAdminService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 功能描述: 商品分发实现类
 * @Author: wangzh
 * @Date: 2022/11/11 9:27
 */
@Service
public class StoreProductDistributeServiceImpl extends ServiceImpl<StoreProductDistributeDao, StoreProductDistribute> implements StoreProductDistributeService {

    @Autowired
    private StoreProductDistributeSublistService storeProductDistributeSublistService;
    @Autowired
    private SystemAdminService systemAdminService;
    @Autowired
    private StoreProductService storeProductService;
    @Autowired
    private IChannelMerchantService channelMerchantService;
    @Autowired
    private SupplierService supplierService;
    @Autowired
    private StoreProductMerService storeProductMerService;

    /**
     * 功能描述: 保存/更新商品组信息
     * @Param: [request]
     * @Return: java.lang.Boolean
     * @Author: wangzh
     * @Date: 2022/11/11 14:11
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Boolean saveProductGroup(StoreProductDistributeRequest request) {
        if (StringUtils.isBlank(request.getProductGroupName())){
            throw new CrmebException("商品组名称不能为空");
        }

        if (CollectionUtils.isEmpty(request.getProductIds())){
            throw new CrmebException("商品不能为空");
        }

        StoreProductDistribute storeProductDistribute = new StoreProductDistribute();
        storeProductDistribute.setId(request.getId())
                .setProductGroupName(request.getProductGroupName())
                .setProductNumber(request.getProductIds().size())
                .setCreatorId(systemAdminService.getAdminId());
        if (request.getId() == null){
            storeProductDistribute.setCreateTime(new Date());
        }

        //存入主表，获取id
        boolean saveGroup = this.saveOrUpdate(storeProductDistribute);
        //删除商品
        storeProductDistributeSublistService.remove(Wrappers.<StoreProductDistributeSublist>lambdaQuery()
                .eq(StoreProductDistributeSublist::getDistributeId, request.getId())
                .notIn(CollectionUtils.isNotEmpty(request.getProductIds()), StoreProductDistributeSublist::getProductId, request.getProductIds()));

        //获取没被删除的商品
        List<StoreProductDistributeSublist> sublistList = storeProductDistributeSublistService.list(Wrappers.<StoreProductDistributeSublist>lambdaQuery()
                .eq(StoreProductDistributeSublist::getDistributeId, request.getId()));
        //没被删除的商品id
        List<Integer> productIds = new ArrayList<>();
        if (Objects.nonNull(sublistList)){
            //未删除的商品添加更新时间
            sublistList = sublistList.stream().peek(e -> e.setUpdateTime(new Date())).collect(Collectors.toList());
            productIds = sublistList.stream().map(StoreProductDistributeSublist::getProductId).collect(Collectors.toList());
        }
        //加入新添加的商品
        for (Integer i : request.getProductIds()){
            if (productIds.contains(i)){
                continue;
            }
            StoreProductDistributeSublist sublist = new StoreProductDistributeSublist();
            sublist.setDistributeId(storeProductDistribute.getId())
                    .setProductId(i)
                    .setCreateTime(new Date());
            sublistList.add(sublist);
        }
        boolean saveSublist = storeProductDistributeSublistService.saveOrUpdateBatch(sublistList);

        return saveGroup && saveSublist;
    }

    /**
     * 功能描述: 根据商品组id获取详情信息
     * @Param: [id]
     * @Return: com.zbkj.crmeb.store.response.StoreProductDistributeResponse
     * @Author: wangzh
     * @Date: 2022/11/11 14:29
     */
    @Override
    public StoreProductDistributeResponse getProductGroupById(Integer id) {
        StoreProductDistributeResponse response = new StoreProductDistributeResponse();
        StoreProductDistribute storeProductDistribute = this.getById(id);
        BeanUtils.copyProperties(storeProductDistribute, response);
        SimpleDateFormat sdf = new SimpleDateFormat(Constants.DATE_FORMAT);
        response.setCreateTime(sdf.format(storeProductDistribute.getCreateTime()));
        response.setUpdateTime(sdf.format(storeProductDistribute.getUpdateTime()));
        List<StoreProductDistributeSublist> list = storeProductDistributeSublistService.list(Wrappers.<StoreProductDistributeSublist>lambdaQuery()
                .eq(StoreProductDistributeSublist::getDistributeId, id));
        //该商品组下所有商品id
        List<Integer> productIds = list.stream().map(StoreProductDistributeSublist::getProductId).collect(Collectors.toList());
        //查询商品信息
        List<StoreProduct> products = storeProductService.getListInIds(productIds);
        response.setProducts(products);
        return response;
    }

    /**
     * 功能描述: 获取商品组列表（分页）
     * @Param: [request]
     * @Return: com.github.pagehelper.PageInfo<com.zbkj.crmeb.store.response.StoreProductDistributeResponse>
     * @Author: wangzh
     * @Date: 2022/11/11 15:24
     */
    @Override
    public PageInfo<StoreProductDistributeResponse> getProductGroupList(String name, PageParamRequest request) {
        Page<Object> pageInfo = PageHelper.startPage(request.getPage(), request.getLimit());
        List<StoreProductDistribute> list = this.list(Wrappers.<StoreProductDistribute>lambdaQuery()
                .like(StringUtils.isNotBlank(name), StoreProductDistribute::getProductGroupName, name)
                .orderByDesc(StoreProductDistribute::getId));
        SimpleDateFormat sdf = new SimpleDateFormat(Constants.DATE_FORMAT);
        List<StoreProductDistributeResponse>  responses = new ArrayList<>();
        for (StoreProductDistribute i : list){
            StoreProductDistributeResponse response = new StoreProductDistributeResponse();
            BeanUtils.copyProperties(i, response);
            response.setCreateTime(sdf.format(i.getCreateTime()));
            response.setUpdateTime(sdf.format(i.getUpdateTime()));
            responses.add(response);
        }

        return CommonPage.copyPageInfo(pageInfo, responses);
    }

    /**
     * 功能描述: 分发商户
     * @Param: [request]
     * @Return: java.lang.Boolean
     * @Author: wangzh
     * @Date: 2022/11/14 11:09
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Boolean distributeProductToSupplier(StoreProductDistributeRequest request) {
        if (CollectionUtils.isEmpty(request.getMerIds())){
            throw new CrmebException("分发商户不能为空");
        }
        List<StoreProductDistributeSublist> list = storeProductDistributeSublistService.list(Wrappers.<StoreProductDistributeSublist>lambdaQuery()
                .eq(StoreProductDistributeSublist::getDistributeId, request.getId()));
        //商品id
        List<Integer> productIds = list.stream().map(StoreProductDistributeSublist::getProductId).collect(Collectors.toList());
        //查询商户是否是供应商
        List<Supplier> suppliers = supplierService.list(Wrappers.<Supplier>lambdaQuery().in(Supplier::getMerId, request.getMerIds()));
        //商户如果是供应商，对应的供应商id
        Map<Integer, Integer> merIdParallelismSupplierIdMap = new HashMap<>();
        if (Objects.nonNull(suppliers)){
            merIdParallelismSupplierIdMap = suppliers.stream().collect(Collectors.toMap(Supplier::getMerId, Supplier::getId));
        }
        //查询商户权限
        List<ChannelMerchant> channelMerchants = channelMerchantService.listByIds(request.getMerIds());
        //商户对应权限map
        Map<Integer, Map<String, List<Integer>>> merchantPowerMap = new HashMap<>();
        for (ChannelMerchant channelMerchant : channelMerchants){
            List<Integer> brandIds = JSON.parseArray(channelMerchant.getBrandIds(), Integer.class);
            List<Integer> tempIds = JSON.parseArray(channelMerchant.getTempId(), Integer.class);
            List<Integer> supplierIds = JSON.parseArray(channelMerchant.getSuppliersIds(), Integer.class);
            if (CollectionUtils.isNotEmpty(supplierIds)){
                if (merIdParallelismSupplierIdMap.get(channelMerchant.getId()) != null){
                    supplierIds.add(merIdParallelismSupplierIdMap.get(channelMerchant.getId()));
                }
            }
            Map<String, List<Integer>> map = new HashMap<>();
            map.put("brandIds", brandIds);
            map.put("tempIds", tempIds);
            map.put("supplierIds", supplierIds);
            merchantPowerMap.put(channelMerchant.getId(), map);
        }
        List<StoreProduct> storeProducts = storeProductService.list(Wrappers.<StoreProduct>lambdaQuery().in(StoreProduct::getId, productIds));

        //商户供应商品id
        List<Integer> merSupplyProductIds = new ArrayList<>();
        List<Boolean> booleans = new ArrayList<>();
        for (Integer i : merchantPowerMap.keySet()){
            //商家有权限的商品id列表
            List<Integer> merProductIds = new ArrayList<>();
            for (StoreProduct storeProduct : storeProducts){
                if (!merchantPowerMap.get(i).get("tempIds").contains(storeProduct.getTempId())){
                    continue;
                }
                if (CollectionUtils.isNotEmpty(merchantPowerMap.get(i).get("supplierIds")) && !merchantPowerMap.get(i).get("supplierIds").contains(storeProduct.getSuppliersId())){
                    continue;
                }
                if (CollectionUtils.isNotEmpty(merchantPowerMap.get(i).get("brandIds")) && !merchantPowerMap.get(i).get("brandIds").contains(storeProduct.getBrandId())){
                    continue;
                }
                //记录该商户供应的商品，后续对是否展示进行设置
                if (Objects.equals(storeProduct.getMerId(), i)){
                    merSupplyProductIds.add(storeProduct.getId());
                }
                merProductIds.add(storeProduct.getId());
            }
            //商户权限下没有商品不上架，判断下个商家
            if (CollectionUtils.isEmpty(merProductIds)){
                continue;
            }
            //进行商品上架
            MybatisPlusConfig.tableNameMp.set(TableNameUtil.getProductMerName(i));
            List<StoreProductMer> updateMerProducts = storeProductMerService.list(Wrappers.<StoreProductMer>lambdaQuery()
                    .in(StoreProductMer::getProductId, merProductIds));
            Map<Integer, StoreProductMer> hasProductMap = new HashMap<>();
            List<StoreProductMer> saveMerProducts = new ArrayList<>();
            if (Objects.nonNull(updateMerProducts)){
                //流获取的对象不会开辟新的地址
                hasProductMap = updateMerProducts.stream().collect(Collectors.toMap(StoreProductMer::getProductId, e -> e));
            }
            for (Integer productId : merProductIds){
                if (hasProductMap.containsKey(productId)){
                    StoreProductMer storeProductMer = hasProductMap.get(productId);
                    storeProductMer.setIsNotShow("0")
                            .setIsSystemOut(0)
                            .setUpdateTime(new Date());
                    continue;
                }
                StoreProductMer storeProductMer = new StoreProductMer();
                storeProductMer.setProductId(productId)
                        .setIsNotShow("0")
                        .setIsSystemOut(0)
                        .setCreateTime(new Date())
                        .setUpdateTime(new Date());
                saveMerProducts.add(storeProductMer);
            }
            //对商户商品表进行修改、添加商品
            boolean save = true;
            boolean update = true;
            //使用动态表名，设置后只对紧跟着的sql生效，不可使用saveOrUpdateBatch()方法进行保存/新增，此方法在插入前会先执行查询操作，之后update操作会报BadSqlGrammarException异常
            //或者不使用mybatis-plus，编写xml文件实现
            //对商户之前没添加过商品进行新增操作
            if (CollectionUtils.isNotEmpty(saveMerProducts)){
                MybatisPlusConfig.tableNameMp.set(TableNameUtil.getProductMerName(i));
                save = storeProductMerService.saveBatch(saveMerProducts);
            }

            //对商户之前添加过的商品进行更新操作
            if (CollectionUtils.isNotEmpty(updateMerProducts)){
                MybatisPlusConfig.tableNameMp.set(TableNameUtil.getProductMerName(i));
                update = storeProductMerService.updateBatchById(updateMerProducts);
            }
            booleans.add(save && update);
        }
        boolean update = true;
        if (CollectionUtils.isNotEmpty(merSupplyProductIds)){
            update = storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                    .set(StoreProduct::getIsShow, 1)
                    .in(StoreProduct::getId, merSupplyProductIds));
        }

        return !booleans.contains(false) && update;
    }

    /**
     * 功能描述: 通过id删除商品分发
     * @Param: [id]
     * @Return: java.lang.Boolean
     * @Author: wangzh
     * @Date: 2022/11/14 13:44
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Boolean deleteProductGroupById(Integer id) {
        boolean remove = this.removeById(id);
        boolean removeSublist = storeProductDistributeSublistService.remove(Wrappers.<StoreProductDistributeSublist>lambdaQuery()
                .eq(StoreProductDistributeSublist::getDistributeId, id));
        return removeSublist && remove;
    }


}
